package com.deer.wms.base.system.service.box.impl;

import com.deer.wms.base.system.dao.box.BoxItemMapper;
import com.deer.wms.base.system.model.box.*;
import com.deer.wms.base.system.model.task.TaskInfo;
import com.deer.wms.base.system.model.task.TaskInfoDto;
import com.deer.wms.base.system.model.ware.CellInfo;
import com.deer.wms.base.system.model.ware.CellInfoDto;
import com.deer.wms.base.system.model.zh.WorkTasks;
import com.deer.wms.base.system.service.box.IBoxItemService;
import com.deer.wms.base.system.service.item.IItemInfoService;
import com.deer.wms.common.core.service.AbstractService;
import com.deer.wms.common.core.text.Convert;
import com.deer.wms.common.utils.DateUtils;
import com.deer.wms.common.utils.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 组盘 服务层实现
 * 
 * @author guo
 * @date 2019-06-03
 */
@Service
@Transactional
 public class BoxItemServiceImpl extends AbstractService<BoxItem, String> implements IBoxItemService
{
	@Autowired
	private BoxItemMapper boxItemMapper;

	@Autowired
	private IBoxItemService boxItemService;


	@Autowired
	private IItemInfoService itemInfoService;


	@Override
	public int BoxItemCount() {
		return boxItemMapper.BoxItemCount();
	}

	@Override
	public int BoxItemByCountState() {
		return boxItemMapper.BoxItemByCountState();
	}

	@Override
	public List<BoxItemDto> getBoxItemDtoInMain(BoxItemCriteria criteria) {
		return boxItemMapper.getBoxItemDtoInMain(criteria);
	}

	@Override
	public int updateBoxItemQuantity(BoxItem boxItem) {
		return boxItemMapper.updateBoxItemQuantity(boxItem);
	}

	@Override
	public List<BoxItemDto> findBoxItemDetail(BoxItemCriteria boxItemCriteria) {
		return boxItemService.findBoxItemDetail(boxItemCriteria);
	}

	@Override
	public BoxItem verifyBoxItem(BoxItem boxItem) {
		return boxItemMapper.verifyBoxItem(boxItem);
	}

	@Override
	public List<BoxItemDto> findTaskStockList(BoxItemCriteria criteria) {
		return boxItemMapper.findTaskStockList(criteria);
	}

	@Override
	public List<BoxItemDto> findTaskExportList() {
		return boxItemMapper.findTaskExportList();
	}

	/**
	 *	关联查询托盘相关信息
	 *
	 * @return
	 */
	@Override
	public List<BoxItemDto> selectBoxItemDtoList(BoxItemCriteria boxItemCriteria) {

		int beginTerm = (StringUtils.isEmpty(boxItemCriteria.getBeginOrEndTerm())) ? 0 : Integer.parseInt(boxItemCriteria.getBeginOrEndTerm());
		LocalDateTime date = LocalDateTime.now();
		// 获取本月第一天
		LocalDateTime firstDay = date.with(TemporalAdjusters.firstDayOfMonth());
		String firstDayStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.parseLocalDateTimeToDate(firstDay));  // firstDayStr----------2020-10-01
		// 获取本月15号
		Date day15th = DateUtils.addDays(DateUtils.parseLocalDateTimeToDate(firstDay), 14);
		String day15thStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, day15th); // day15thStr----------2020-10-15
		// 获取本月最后一天
		LocalDateTime lastDay = date.with(TemporalAdjusters.lastDayOfMonth());
		String lastDayStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.parseLocalDateTimeToDate(lastDay)); //	lastDayStr----------2020-10-31
		// 期初
		if (1 == beginTerm) {
			boxItemCriteria.setStartTime(firstDayStr);
			boxItemCriteria.setEndTime(day15thStr);
		} else if (2 == beginTerm) { // 期末
			boxItemCriteria.setStartTime(day15thStr);
			boxItemCriteria.setEndTime(lastDayStr);
		}
		return boxItemMapper.selectBoxItemDtoList(boxItemCriteria);
	}

	/**
	 * 根据托盘编码寻找所有在货位上的托盘信息  便于统计数据
	 *
	 * @param itemCode
	 * @return
	 */
	@Override
	public List<BoxItemDto> getBoxItemDtoByitemCode(String itemCode) {

		return boxItemMapper.getBoxItemDtoByitemCode(itemCode);
	}

	/**
	 * 根据任务id查询托盘信息
	 *
	 * @param taskId
	 * @return
	 */
	@Override
	public BoxItem getBoxItemByTaskId(String taskId) {

		return boxItemMapper.getBoxItemByTaskId(taskId);
	}

	/**
	 * 根据物料编码查询货位信息  (根据批次排序， 保证先进先出)
	 *
	 * @param itemCode
	 * @return
	 */
	@Override
	public List<BoxItemDto> getFullCellInfoForOutOfStock(String itemCode) {

		return boxItemMapper.getFullCellInfoForOutOfStock(itemCode);
	}

	/**
	 *
	 * 出库任务，寻找合适的出库货位(根据货物编码)
	 *
	 * @param itemCode
	 * @param quantity
	 * @return   返回类型集合， 当最早批次货位货物数量不够时，继续用别的货位,一直不够就一直加，直到所有货位都出货
	 */
	@Override
	public List<BoxItemDto> getFullCellInfoForOutOfStockForSaveTaskInfo(@Param("itemCode") String itemCode,@Param("quantity") Integer quantity) {
		List<BoxItemDto> boxItemDtos = boxItemService.getFullCellInfoForOutOfStock(itemCode);
		if(boxItemDtos != null){
			Integer quantitys = 0;
			int count = 0;
			/*for(BoxItemDto boxItemDto : boxItemDtos){
				quantitys += boxItemDto.getQuantity();
				//当需要的数量<可取出的数量
				if(quantity < quantitys){
					//如果第一次循环就也满足上面条件，则就取第一个元素作为新集合返回
					if(count == 0){
						List<BoxItemDto> fistBoxItemDto = new ArrayList<BoxItemDto>();
						fistBoxItemDto.add(boxItemDto);
						return fistBoxItemDto;
					}
					//如果超过1次循环,则截取一个新的集合返回
					List<BoxItemDto> newBoxItemDtos = boxItemDtos.subList(0,count+1);
					return newBoxItemDtos;
				}
				count++;
				//如果计已经达到集合长度，表示货物不足， 直接返回该集合，全出
				if(count == boxItemDtos.size()){
					return boxItemDtos;
				}
			}*/
		}
		return null;
	}

	/**
	 * 根据 托盘编码查找托盘
	 *
	 * @param boxCode
	 * @return
	 */
	@Override
	public BoxItem getBoxItemByBoxCode(String boxCode) {
		return boxItemMapper.getBoxItemByBoxCode(boxCode);
	}

	@Override
	public BoxItemDto billOutGetBoxItemByBoxCode(String boxCode) {
		return boxItemMapper.billOutGetBoxItemByBoxCode(boxCode);
	}

	/**
     * 查询组盘信息
     * 
     * @param id 组盘ID
     * @return 组盘信息
     */
    @Override
	public BoxItemDto selectBoxItemById(Integer id)
	{
	    return boxItemMapper.selectBoxItemById(id);
	}
	
	/**
     * 查询组盘列表
     * 
     * @param boxItem 组盘信息
     * @return 组盘集合
     */
	@Override
	public List<BoxItem> selectBoxItemList(BoxItem boxItem)
	{
	    return boxItemMapper.selectBoxItemList(boxItem);
	}
	
    /**
     * 新增组盘
     * 
     * @param boxItem 组盘信息
     * @return 结果
     */
	@Override
	public int insertBoxItem(BoxItem boxItem)
	{
	    return boxItemMapper.insertBoxItem(boxItem);
	}


	/**
     * 修改组盘
     * 
     * @param boxItem 组盘信息
     * @return 结果
     */
	@Override
	public int updateBoxItem(BoxItem boxItem)
	{
	    return boxItemMapper.updateBoxItem(boxItem);
	}

	@Override
	public void deleteByBoxCode(String boxCode){
		boxItemMapper.deleteByBoxCode(boxCode);
	}

	/**
     * 删除组盘对象
     * 
     * @param ids 需要删除的数据ID
     * @return 结果
     */
	@Override
	public int deleteBoxItemByIds(String ids)
	{
		return boxItemMapper.deleteBoxItemByIds(Convert.toStrArray(ids));
	}

	@Override
	public int deleteBoxItemById(Long id) {
		return boxItemMapper.deleteBoxItemById(id);
	}

	/**
	 * 根据id升序查找第一个可合框物料
	 */
	public BoxItem findOneCombineBoxGroupByItemCodeAndBatch(){
		return boxItemMapper.findOneCombineBoxGroupByItemCodeAndBatch();
	}

	public List<BoxItemDto> findMoreCombineBoxByItemCodeAndBatch(BoxItem boxItem){
		return boxItemMapper.findMoreCombineBoxByItemCodeAndBatch(boxItem);
	}

	public List<BoxItemDto> findByWorkerOrder(BoxItemCriteria criteria){
		return boxItemMapper.findByWorkerOrder(criteria);
	}

	/**
	 * 跟物料编码查询合适的托盘进行预测备料
	 * @return
	 */
	@Override
	public List<BoxItemDto> findSuitByItemCodeAndQuantity(@Param("itemCode") String itemCode,@Param("quantity") Integer quantity) {
		List<BoxItemDto> boxItemDtos = boxItemService.getFullCellInfoForOutOfStock(itemCode);
		if(boxItemDtos != null){
			Integer quantitys = 0;
			int count = 0;
			List<BoxItemDto> lists = new ArrayList<BoxItemDto>();
			for(BoxItemDto boxItemDto : boxItemDtos){
				//quantitys += boxItemDto.getQuantity()-boxItemDto.getForecastStockQuantity();
				//当需要的数量小于等于托盘中可出数量
				if(quantity<=quantitys){
					//如果第一次循环就也满足上面条件，则就取第一个元素作为新集合返回
					if(count == 0){
						lists.add(boxItemDto);
						return lists;
					}
					//如果超过1次循环,则截取一个新的集合返回
					lists = boxItemDtos.subList(0,count+1);
					return lists;
				}
				count++;
			}
		}
		return null;
	}

	@Override
	public List<BoxItemDto> findList(BoxItemCriteria criteria){
		return boxItemMapper.findList(criteria);
	}

	@Override
	public List<BoxItemDto> findSluggishOverdue(BoxItemCriteria criteria){
		return boxItemMapper.findSluggishOverdue(criteria);
	}

	@Override
	public List<BoxItemDto> findWillOverdue(BoxItemCriteria criteria){
		return boxItemMapper.findWillOverdue(criteria);
	}

	@Override
	public List<BoxItemDto> findBoxItemList(BoxItemCriteria criteria){
		return boxItemMapper.findBoxItemList(criteria);
	}


	@Override
	public List<BoxItemDto> workerOrderLackOut(BoxItemCriteria criteria){
		return boxItemMapper.workerOrderLackOut(criteria);
	}

	@Override
	public 	List<UnqualifiedOverTakeCanDelayDays> findUnqualifiedOverTakeCanDelayDays(BoxItemCriteria criteria)
	{
		return boxItemMapper.findUnqualifiedOverTakeCanDelayDays(criteria);
	}

	@Override
	public List<BoxItemDto> findListByItemCode(BoxItemDto boxItemDto) {
		return boxItemMapper.findListByItemCode(boxItemDto);
	}

	@Override
	public BoxItemDto assignBillOutFindBoxCode(BoxItemDto boxItemDto) {
		return boxItemMapper.assignBillOutFindBoxCode(boxItemDto);
	}

	@Override
	public Integer getSumQuantityByItemCode(BoxItem boxItem) {
		return boxItemMapper.getSumQuantityByItemCode(boxItem);
	}

	@Override
	public BoxItemDto selectBoxItemByBoxCode(String boxCode) {
		return boxItemMapper.selectBoxItemByBoxCode(boxCode);
	}

	@Override
	public BoxItemDto selectBoxItemByboxItemDto(BoxItemDto boxItemDto) {
		return boxItemMapper.selectBoxItemByboxItemDto(boxItemDto);
	}

	@Override
	public List<StockOverviewDto> findStockOverviewList(StockOverviewDto stockOverviewDto) {
		List<StockOverviewDto> stockOverviewList = boxItemMapper.findStockOverviewList(stockOverviewDto);
		for (StockOverviewDto dto : stockOverviewList) {
			//String itemCode = dto.getItemCode();
			//int sum = boxItemMapper.selectSumQuantityByItemCode(itemCode);
			//dto.setItemSumTotal(sum);
		}
		return stockOverviewList;
	}

	@Override
	public List<StockOverViewDo> findExportList() {
		return boxItemMapper.findExportList();
	}

	@Override
	public List<BoxItemDto> assignBoxItem(BoxItemDto boxItemDto) {
		return boxItemMapper.assignBoxItem(boxItemDto);
	}

	@Override
	public int blockedBoxItem(Long id) {
		return boxItemMapper.blockedBoxItem(id);
	}

	@Override
	public int unfreezeBoxItem(Long id) {
		return boxItemMapper.unfreezeBoxItem(id);
	}

	@Override
	public List<BoxItemDto> selectBoxItemLine(BoxItemDto boxItemDto) {
		return boxItemMapper.selectBoxItemLine(boxItemDto);
	}

	@Override
	public List<BoxItemDto> findBoxItemByItemId(Integer itemId) {
		return boxItemMapper.findBoxItemByItemId(itemId);
	}

	@Override
	public void insertBoxItemEdge(BoxItemDto boxItem) {
		boxItemMapper.insertBoxItemEdge(boxItem);
	}

	@Override
	public void saveBoxItemByTaskNumber(TaskInfo taskInfo) {
		boxItemMapper.saveBoxItemByTaskNumber(taskInfo);
	}

	@Override
	public void updateBySapId(Integer billInSapId) {
		boxItemMapper.updateBySapId(billInSapId);
	}

	@Override
	public void updateBoxItemEdgeByBatch(WorkTasks workTasks) {
		boxItemMapper.updateBoxItemEdgeByBatch(workTasks);
	}

	@Override
	public void updatetBoxItemByDetailId(BoxItem boxItem) {
		boxItemMapper.updatetBoxItemByDetailId(boxItem);
	}

	@Override
	public List<BoxItemDto> findBoxItemBatch() {
		return boxItemMapper.findBoxItemBatch();
	}

	@Override
	public List<CellInfo> findPai(CellInfo cellInfo) {
		return boxItemMapper.findPai(cellInfo);
	}

	@Override
	public List<CellInfo> findLie(CellInfo cellInfo) {
		return boxItemMapper.findLie(cellInfo);
	}

	@Override
	public List<CellInfo> findCeng(CellInfo cellInfo) {
		return boxItemMapper.findCeng(cellInfo);
	}

	@Override
	public List<CellInfo> findCell(CellInfo cellInfo) {
		return boxItemMapper.findCell(cellInfo);
	}

	@Override
	public CellInfoDto findCellById(Integer id) {
		return boxItemMapper.findCellById(id);
	}

	@Override
	public void updateBoxItemCell(BoxItemDto boxItemDto) {
		boxItemMapper.updateBoxItemCell(boxItemDto);
	}

	@Override
	public void updateBoxItemState(String cellCode) {
		boxItemMapper.updateBoxItemState(cellCode);
	}

	@Override
	public Float findBoxItemEdgeByBatch(WorkTasks workTask) {
		return boxItemMapper.findBoxItemEdgeByBatch(workTask);
	}

	@Override
	public void delBoxItem(WorkTasks workTask) {
		boxItemMapper.delBoxItem(workTask);
	}

	@Override
	public int findEdgeSumByBatch(WorkTasks workTask) {
		return boxItemMapper.findEdgeSumByBatch(workTask);
	}

	@Override
	public void updateBillInState(BoxItemDto boxItem) {
		boxItemMapper.updateBillInState(boxItem);
	}

	@Override
	public void updateBatch(BoxItemDto boxItem) {
		boxItemMapper.updateBatch(boxItem);
	}

	@Override
	public BoxItemDto findBoxItemMSG(Long id) {
		return boxItemMapper.findBoxItemMSG(id);
	}

	@Override
	public void insertBoxItemState(BoxItemState boxItemState) {
		boxItemMapper.insertBoxItemState(boxItemState);
	}

	@Override
	public void insertBoxItemStateDetail(BoxItemStateDetail boxItemStateDetail) {
		boxItemMapper.insertBoxItemStateDetail(boxItemStateDetail);
	}

	@Override
	public List<BoxItemStateDetail> selectBoxItemStateList(BoxItemStateDetail boxItemStateDetail) {
		return boxItemMapper.selectBoxItemStateList(boxItemStateDetail);
	}

	@Override
	public BoxItemState findStateById(Integer stateId) {
		return boxItemMapper.findStateById(stateId);
	}

	@Override
	public List<BoxItemStateDetail> findListdetail(Integer stateId) {
		return boxItemMapper.findListdetail(stateId);
	}

	@Override
	public List<BoxItemDto> findBoxBatchByItemId(Integer itemId) {
		return boxItemMapper.findBoxBatchByItemId(itemId);
	}

	@Override
	public void outBoxItem(Long id) {
		boxItemMapper.outBoxItem(id);
	}

    @Override
    public void insertBoxItemBatch(BoxItemBatch boxItemBatch) {
        boxItemMapper.insertBoxItemBatch(boxItemBatch);
    }

    @Override
    public void insertBoxItemBatchDetail(BoxItemBatchDetail boxItemBatchDetail) {
        boxItemMapper.insertBoxItemBatchDetail(boxItemBatchDetail);
    }

	@Override
	public List<BoxItemBatchDetail> selectBoxItemBatchList(BoxItemBatchDetail boxItemBatchDetail) {
		return boxItemMapper.selectBoxItemBatchList(boxItemBatchDetail);
	}

	@Override
	public BoxItemBatchDetail selectBoxItemBatch(int id) {
		return boxItemMapper.selectBoxItemBatch(id);
	}

	@Override
	public void updateExcelBatchState(int id) {
		boxItemMapper.updateExcelBatchState(id);
	}

	@Override
	public BoxItemStateDetail selectBoxItemState(int id) {
		return boxItemMapper.selectBoxItemState(id);
	}

	@Override
	public void updateExcelStateState(int id) {
		boxItemMapper.updateExcelStateState(id);
	}

	@Override
	public List<BoxItemDto> selectBoxItemWarning(BoxItemDto boxItemDto) {
		return boxItemMapper.selectBoxItemWarning(boxItemDto);
	}

	@Override
	public List<BoxItemToday> selectBoxItemToday(BoxItemToday boxItemToday) {
		return boxItemMapper.selectBoxItemToday(boxItemToday);
	}

	@Override
	public List<BoxItemDto> findBoxItemAll(BoxItemDto boxItemDto) {
		return boxItemMapper.findBoxItemAll(boxItemDto);
	}

	@Override
	public List<BoxItemToday> selectBoxItemHistory(BoxItemToday boxItemToday) {
		return boxItemMapper.selectBoxItemHistory(boxItemToday);
	}

	@Override
	public BoxItemDto findByItemId(Long id) {
		return boxItemMapper.findByItemId(id);
	}

	@Override
	public BoxItemDto selectBoxItemAll(BoxItemDto boxItemDto) {
		return boxItemMapper.selectBoxItemAll(boxItemDto);
	}

	@Override
	public List<BoxItem> findBoxItemByCarrierId(BoxItemCriteria boxItemCriteria) {
		return boxItemMapper.findBoxItemByCarrierId(boxItemCriteria);
	}

	@Override
	public  List<BoxItemDto> selectRevolutionStorageList(BoxItemCriteria boxItemCriteria) {
		return boxItemMapper.selectRevolutionStorageList(boxItemCriteria);
	}

	@Override
	public BoxItem findIdByCarrierId(String carrierId) {
		return boxItemMapper.findIdByCarrierId(carrierId);
	}

	@Override
	public  List<BoxItemDto> getQuantityByShelfId(Integer shelfId) {
		return boxItemMapper.getQuantityByShelfId(shelfId);
	}

	@Override
	public List<BoxItemDto> findBoxItemDtoListByAreaId(BoxItemCriteria boxItemCriteria) {
		return boxItemMapper.findBoxItemDtoListByAreaId(boxItemCriteria);
	}

	@Override
	public List<BoxItemDto> boxPandect(BoxItemCriteria boxItemCriteria) {
		return boxItemMapper.boxPandect(boxItemCriteria);
	}

	@Override
	public List<BoxItemDto> findBoxItemDtoDetailByAreaId(BoxItemCriteria boxItemCriteria) {
		return boxItemMapper.findBoxItemDtoDetailByAreaId(boxItemCriteria);
	}

	@Override
	public List<BoxItemExport> findBoxItemDtoMainListByAreaId(BoxItemCriteria boxItemCriteria) {
		return boxItemMapper.findBoxItemDtoMainListByAreaId(boxItemCriteria);
	}

	@Override
	public List<BoxItemDto> selectBoxItem(BoxItemDto boxItemDto) {
		return boxItemMapper.selectBoxItem(boxItemDto);
	}
	
	@Override
	public List<BoxItemDto> selectBoxItemDetail(BoxItemDto boxItemDto) {
		return boxItemMapper.selectBoxItemDetail(boxItemDto);
	}
	@Override
	public BoxItemDto findBoxItemMsgByTaskNumber(WorkTasks workTasks) {
		return boxItemMapper.findBoxItemMsgByTaskNumber(workTasks).get(0);
	}




/*	public static void main(String[] args) {
		LocalDateTime date = LocalDateTime.now();

		// 获取本月第一天
		LocalDateTime firstDay = date.with(TemporalAdjusters.firstDayOfMonth());
		String firstDayStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.parseLocalDateTimeToDate(firstDay));
		// 获取本月15号
		Date day15th = DateUtils.addDays(DateUtils.parseLocalDateTimeToDate(firstDay), 14);
		String day15thStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, day15th);
		// 获取本月最后一天
		LocalDateTime lastDay = date.with(TemporalAdjusters.lastDayOfMonth());
		String lastDayStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.parseLocalDateTimeToDate(lastDay));

		System.out.println("firstDayStr----------"+firstDayStr);
		System.out.println("day15thStr----------"+day15thStr);
		System.out.println("lastDayStr----------"+lastDayStr);
	}*/

}
